<?php
/**
 * DB类
 *
 * @package if
 * @subpackage module.db
 * @since 1.0
 */
class IDb extends IObject {
	const TYPE_INT = 1;
	const TYPE_LONG = 2;
	const TYPE_BOOL = 3;
	const TYPE_LOB = 4;
	const TYPE_NULL = 5;
	const TYPE_STR = 6;
	const TYPE_FLOAT = 7;
	const TYPE_DATE = 8;
	const TYPE_TIME = 9;
	const TYPE_TIMESTAMP = 10;
	
	const FETCH_ASSOC = 2;
	const FETCH_NUM = 3;
	const FETCH_BOTH = 4;
	const FETCH_OBJ = 5;
	const FETCH_COLUMN = 7;
	
	private static $drivers = array(
		"mysql" => "IDbMysqlDriver",
		"mysqli" => "IDbMysqliDriver",
		"mssql" => "IDbMssqlDriver",
		"sqlite" => "IDbSqliteDriver",
		"postgres" => "IDbPostgresDriver",
		"pdo_mysql" => "IDbPdoMysql",
		"pdo_mssql" => "IDbPdoMssql",
		"pdo_sqlite" => "IDbPdoSqlite",
		"pdo_sqlite2" => "IDbPdoSqlite2",
		"pdo_sqlite3" => "IDbPdoSqlite3",
		"pdo_postgres" => "IDbPdoPostgres"
	);
	
	private static $fetchModes = array(
		self::FETCH_ASSOC, 
		self::FETCH_NUM, 
		self::FETCH_BOTH, 
		self::FETCH_OBJ, 
		self::FETCH_COLUMN  
	);
	
	private static $driverObjs = array();
	
	/**
	 * 取得驱动
	 *
	 * @param string $name 驱动名
	 * @param array $config 配置
	 * @return IDbDriver
	 * @since 1.0
	 */
	static function driver($name, $config) {
		$_name = strtolower($name);
		$_config = serialize($config);
		$_uniqueKey = $name . "://" . $_config;
		if (array_key_exists($_uniqueKey, self::$driverObjs)) {
			return self::$driverObjs[$_uniqueKey];
		}
		if (array_key_exists($_name, self::$drivers)) {
			$driverName = self::$drivers[$_name];
			$driverObj = new $driverName($config);
			self::$driverObjs[$_uniqueKey] = $driverObj;
			$driverObj->setName($_name);
			return $driverObj;
		}
		throw new IDbException("unsupported driver '{$name}'", 0x100087);
	}
	
	/**
	 * 使用配置名获取驱动
	 * 
	 * 从1.0.2开始，name默认为default
	 *
	 * @param string $name 配置名
	 * @return IDbDriver
	 * @since 1.0
	 */
	static function driverByOpt($name = "default") {
		$opts = o("@db." . $name);
		if (!is_array($opts)) {
			throw new IDbException("no options for driver config '" . $name . "'", 0x100088);
		}
		if (!isset($opts["driver"])) {
			throw new IDbException("no driver is decleared", 0x100089);
		}
		$driver = self::driver($opts["driver"], $opts);
		return $driver;
	}
	
	/**
	 * 判断FETCH_MODE是否被支持
	 * 
	 * 目前支持IDb::FETCH_*
	 *
	 * @param integer $fetchMode 取的记录行的方式
	 * @return boolean
	 * @since 1.0
	 */
	static function isSupportedFetchMode($fetchMode) {
		return in_array($fetchMode, self::$fetchModes, true);
	}
	
	/**
	 * 取得所有数据库驱动的类名
	 *
	 * @return array
	 * @since 1.1.2
	 */
	static function driverClasses() {
		return self::$drivers;
	}
}

?>